{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import vectorbt as vbt\n",
    "from datetime import timedelta"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2018-01-01 12:00:00    0.374540\n",
      "2018-01-01 13:00:00    0.950714\n",
      "2018-01-01 14:00:00    0.731994\n",
      "2018-01-01 15:00:00    0.598658\n",
      "2018-01-01 16:00:00    0.156019\n",
      "2018-01-01 17:00:00    0.155995\n",
      "2018-01-01 18:00:00    0.058084\n",
      "2018-01-01 19:00:00    0.866176\n",
      "2018-01-01 20:00:00    0.601115\n",
      "2018-01-01 21:00:00    0.708073\n",
      "2018-01-01 22:00:00    0.020584\n",
      "2018-01-01 23:00:00    0.969910\n",
      "2018-01-02 00:00:00    0.832443\n",
      "2018-01-02 01:00:00    0.212339\n",
      "2018-01-02 02:00:00    0.181825\n",
      "2018-01-02 03:00:00    0.183405\n",
      "2018-01-02 04:00:00    0.304242\n",
      "2018-01-02 05:00:00    0.524756\n",
      "2018-01-02 06:00:00    0.431945\n",
      "2018-01-02 07:00:00    0.291229\n",
      "2018-01-02 08:00:00    0.611853\n",
      "2018-01-02 09:00:00    0.139494\n",
      "2018-01-02 10:00:00    0.292145\n",
      "2018-01-02 11:00:00    0.366362\n",
      "2018-01-02 12:00:00    0.456070\n",
      "2018-01-02 13:00:00    0.785176\n",
      "2018-01-02 14:00:00    0.199674\n",
      "2018-01-02 15:00:00    0.514234\n",
      "2018-01-02 16:00:00    0.592415\n",
      "2018-01-02 17:00:00    0.046450\n",
      "2018-01-02 18:00:00    0.607545\n",
      "2018-01-02 19:00:00    0.170524\n",
      "2018-01-02 20:00:00    0.065052\n",
      "2018-01-02 21:00:00    0.948886\n",
      "2018-01-02 22:00:00    0.965632\n",
      "2018-01-02 23:00:00    0.808397\n",
      "2018-01-03 00:00:00    0.304614\n",
      "2018-01-03 01:00:00    0.097672\n",
      "2018-01-03 02:00:00    0.684233\n",
      "2018-01-03 03:00:00    0.440152\n",
      "2018-01-03 04:00:00    0.122038\n",
      "2018-01-03 05:00:00    0.495177\n",
      "2018-01-03 06:00:00    0.034389\n",
      "2018-01-03 07:00:00    0.909320\n",
      "2018-01-03 08:00:00    0.258780\n",
      "2018-01-03 09:00:00    0.662522\n",
      "2018-01-03 10:00:00    0.311711\n",
      "2018-01-03 11:00:00    0.520068\n",
      "Freq: H, dtype: float64\n"
     ]
    }
   ],
   "source": [
    "# Generate sample price\n",
    "price_idx = pd.date_range('2018-01-01 12:00:00', periods=48, freq='H')\n",
    "np.random.seed(42)\n",
    "price = pd.Series(np.random.uniform(size=price_idx.shape), index=price_idx)\n",
    "print(price)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2018-01-01 00:00:00   NaN\n",
      "2018-01-01 01:00:00   NaN\n",
      "2018-01-01 02:00:00   NaN\n",
      "2018-01-01 03:00:00   NaN\n",
      "2018-01-01 04:00:00   NaN\n",
      "                       ..\n",
      "2018-01-03 20:00:00   NaN\n",
      "2018-01-03 21:00:00   NaN\n",
      "2018-01-03 22:00:00   NaN\n",
      "2018-01-03 23:00:00   NaN\n",
      "2018-01-04 00:00:00   NaN\n",
      "Freq: H, Length: 73, dtype: float64\n"
     ]
    }
   ],
   "source": [
    "# Sessions must be equal - fill missing dates\n",
    "# Fill on first date before 12:00 and on last date after 11:00\n",
    "first_date = price.index[0].date()\n",
    "last_date = price.index[-1].date()+timedelta(days=1)\n",
    "filled_idx = pd.date_range(first_date, last_date, freq='H')\n",
    "filled_price = price.reindex(filled_idx)\n",
    "print(filled_price)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2018-01-01 09:00:00         NaN\n",
      "2018-01-01 10:00:00         NaN\n",
      "2018-01-01 11:00:00         NaN\n",
      "2018-01-01 12:00:00    0.374540\n",
      "2018-01-01 13:00:00    0.950714\n",
      "2018-01-01 14:00:00    0.731994\n",
      "2018-01-01 15:00:00    0.598658\n",
      "2018-01-01 16:00:00    0.156019\n",
      "2018-01-02 09:00:00    0.139494\n",
      "2018-01-02 10:00:00    0.292145\n",
      "2018-01-02 11:00:00    0.366362\n",
      "2018-01-02 12:00:00    0.456070\n",
      "2018-01-02 13:00:00    0.785176\n",
      "2018-01-02 14:00:00    0.199674\n",
      "2018-01-02 15:00:00    0.514234\n",
      "2018-01-02 16:00:00    0.592415\n",
      "2018-01-03 09:00:00    0.662522\n",
      "2018-01-03 10:00:00    0.311711\n",
      "2018-01-03 11:00:00    0.520068\n",
      "2018-01-03 12:00:00         NaN\n",
      "2018-01-03 13:00:00         NaN\n",
      "2018-01-03 14:00:00         NaN\n",
      "2018-01-03 15:00:00         NaN\n",
      "2018-01-03 16:00:00         NaN\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "# Remove dates that are outside of trading sessions\n",
    "session_price_idx = filled_price.between_time('9:00', '17:00', include_end=False).index\n",
    "session_price = filled_price.loc[session_price_idx]\n",
    "print(session_price)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "split_idx         0         1         2\n",
      "0               NaN  0.139494  0.662522\n",
      "1               NaN  0.292145  0.311711\n",
      "2               NaN  0.366362  0.520068\n",
      "3          0.374540  0.456070       NaN\n",
      "4          0.950714  0.785176       NaN\n",
      "5          0.731994  0.199674       NaN\n",
      "6          0.598658  0.514234       NaN\n",
      "7          0.156019  0.592415       NaN\n"
     ]
    }
   ],
   "source": [
    "# Select first and last ticks of each trading session and split price into ranges between those ticks\n",
    "start_idxs = session_price.index[session_price.index.hour == 9]\n",
    "end_idxs = session_price.index[session_price.index.hour == 16]\n",
    "price_per_session, _ = session_price.vbt(freq='1H').range_split(start_idxs=start_idxs, end_idxs=end_idxs)\n",
    "print(price_per_session)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0   -0.786858\n",
      "1    1.466807\n",
      "2   -0.529509\n",
      "Name: total_return, dtype: float64\n"
     ]
    }
   ],
   "source": [
    "# Run your strategy (here using random signals)\n",
    "entries, exits = pd.DataFrame.vbt.signals.generate_random_both(price_per_session.shape, n=2, seed=42)\n",
    "pf = vbt.Portfolio.from_signals(price_per_session, entries, exits, freq='1H')\n",
    "print(pf.total_return())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "widgets": {
   "application/vnd.jupyter.widget-state+json": {
    "state": {},
    "version_major": 2,
    "version_minor": 0
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
